package cn.seqdata.javatime;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.function.UnaryOperator;

public enum RelativeDate implements UnaryOperator<LocalDate> {
	/**
	 * 今天
	 */
	TODAY(0, ChronoUnit.DAYS, UnaryOperator.identity()),
	/**
	 * 昨天
	 */
	YESTERDAY(-1, ChronoUnit.DAYS, DateUtils::minusDay),
	/**
	 * 明天
	 */
	TOMORROW(1, ChronoUnit.DAYS, DateUtils::plusDay),
	/**
	 * 本周
	 */
	THE_WEEK(0, ChronoUnit.WEEKS, DateUtils::startOfWeek),
	/**
	 * 上周
	 */
	LAST_WEEK(-1, ChronoUnit.WEEKS, date -> DateUtils.minusWeek(THE_WEEK.apply(date))),
	/**
	 * 下周
	 */
	NEXT_WEEK(1, ChronoUnit.WEEKS, date -> DateUtils.plusWeek(THE_WEEK.apply(date))),
	/**
	 * 本月
	 */
	THE_MONTH(0, ChronoUnit.MONTHS, DateUtils::startOfMonth),
	/**
	 * 上月
	 */
	LAST_MONTH(-1, ChronoUnit.MONTHS, date -> DateUtils.minusMonth(THE_MONTH.apply(date))),
	/**
	 * 下月
	 */
	NEXT_MONTH(1, ChronoUnit.MONTHS, date -> DateUtils.plusMonth(THE_MONTH.apply(date))),
	/**
	 * 今年
	 */
	THE_YEAR(0, ChronoUnit.YEARS, DateUtils::startOfYear),
	/**
	 * 去年
	 */
	LAST_YEAR(-1, ChronoUnit.YEARS, date -> DateUtils.minusYear(THE_YEAR.apply(date))),
	/**
	 * 明年
	 */
	NEXT_YEAR(1, ChronoUnit.YEARS, date -> DateUtils.plusYear(THE_YEAR.apply(date)));

	public final int value;
	public final ChronoUnit unit;
	private final UnaryOperator<LocalDate> start;

	RelativeDate(int value, ChronoUnit unit, UnaryOperator<LocalDate> start) {
		this.value = value;
		this.unit = unit;
		this.start = start;
	}

	@Override
	public LocalDate apply(LocalDate date) {
		return start.apply(date);
	}

	public DateInterval toInterval(LocalDate date) {
		return new DateInterval(apply(date), unit);
	}
}
